package common.io
{
    import flash.display.InteractiveObject;
    import flash.display.Stage;
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.events.FocusEvent;
    import flash.events.IEventDispatcher;
    import flash.events.KeyboardEvent;
    import flash.system.IME;
    import flash.text.TextField;
    import flash.text.TextFieldType;
    import flash.ui.Keyboard;

    import kernel.application.ApplicationDisplay;

    /**
     * <p>events:</p><br>
     *
     * keyDownHandler(self:KeyboardManager, type:uint=keyCodeValue, charCodeValue:uint, keyLocationValue:uint, ctrlKeyValue:Boolean, altKeyValue:Boolean, shiftKeyValue:Boolean)
     * keyUpHandler(self:KeyboardManager, type:uint=Keyboard.KEY_UP, charCodeValue:uint, keyCodeValue:uint, keyLocationValue:uint, ctrlKeyValue:Boolean, altKeyValue:Boolean, shiftKeyValue:Boolean)
     */

    public class KeyboardManager implements IEventDispatcher
    {
        public static const instance:KeyboardManager = new KeyboardManager ();

        public static const KEY_0:int = 48;
        public static const KEY_1:int = 49;
        public static const KEY_2:int = 50;
        public static const KEY_3:int = 51;
        public static const KEY_4:int = 52;
        public static const KEY_5:int = 53;
        public static const KEY_6:int = 54;
        public static const KEY_7:int = 55;
        public static const KEY_8:int = 56;
        public static const KEY_9:int = 57;
        public static const KEY_10:int = 189;
        public static const KEY_11:int = 187;
        public static const KEY_A:int = 65;
        public static const KEY_B:int = 66;
        public static const KEY_C:int = 67;
        public static const KEY_D:int = 68;
        public static const KEY_F:int = 70;
        public static const KEY_H:int = 72;
        public static const KEY_I:int = 73;
        public static const KEY_K:int = 75;
        public static const KEY_L:int = 76;
        public static const KEY_M:int = 77;
        public static const KEY_N:int = 78;
        public static const KEY_O:int = 79;
        public static const KEY_P:int = 80;
        public static const KEY_Q:int = 81;
        public static const KEY_S:int = 83;
        public static const KEY_T:int = 84;
        public static const KEY_U:int = 85;
        public static const KEY_W:int = 87;
        public static const KEY_X:int = 88;
        public static const KEY_Z:int = 90;
        public static const KEY_ESC:int = 27;
        public static const KEY_ENTER:int = 13;
        public static const KEY_TAB:int = 9;
        public static const KEY_CTRL:int = 17;

        public static const KEY_SHIFT:int = 16;
        public static const KEY_SPACE:int = 32;

        private var _shortcutKeyList:Array;

        private var _lockCount:int;
        private var _focus:InteractiveObject;

        private var _stage:Stage;

        private var _eventdispatcher:EventDispatcher;

        public function KeyboardManager():void
        {
            _shortcutKeyList = [];
            _registShortcutKey ();
            _lockCount = 0;
            _eventdispatcher = new EventDispatcher (this);
//			this.lock();
        }



        public function addKeyDownListener(keyCode:uint , listener:Function):void
        {
            this._eventdispatcher.addEventListener (KeyboardEvent.KEY_DOWN + "_" + keyCode , listener);
        }

        public function addKeyUpListener(keyCode:uint , listener:Function):void
        {
            this._eventdispatcher.addEventListener (KeyboardEvent.KEY_UP + "_" + keyCode , listener);
        }

        public function removeKeyDownListener(keyCode:uint , listener:Function):void
        {
            _eventdispatcher.removeEventListener (KeyboardEvent.KEY_DOWN + "_" + keyCode , listener);
        }

        public function removeKeyUpListener(keyCode:uint , listener:Function):void
        {
            _eventdispatcher.removeEventListener (KeyboardEvent.KEY_UP + "_" + keyCode , listener);
        }

        public function dispatchEvent(event:Event):Boolean
        {

            var tf:TextField = _stage.focus as TextField;
            if (tf != null && tf.type == TextFieldType.INPUT)
                return false;
            return _eventdispatcher.dispatchEvent (event);

        }

        public function removeEventListener(type:String , listener:Function , useCapture:Boolean = false):void
        {
            return _eventdispatcher.removeEventListener (type , listener , useCapture);
        }

        public function hasEventListener(type:String):Boolean
        {
            return _eventdispatcher.hasEventListener (type);
        }

        public function willTrigger(type:String):Boolean
        {
            return _eventdispatcher.willTrigger (type);
        }

        public function addEventListener(type:String , listener:Function , useCapture:Boolean = false , priority:int = 0 , useWeakReference:Boolean = false):void
        {
            return _eventdispatcher.addEventListener (type , listener , useCapture , priority , useWeakReference);
        }

        public function initialized():void
        {

            _stage = ApplicationDisplay.stage;

            _stage.addEventListener (KeyboardEvent.KEY_DOWN , _stageKeyDownHandler);
            _stage.addEventListener (KeyboardEvent.KEY_UP , _stageKeyUpHandler);
            _stage.addEventListener (FocusEvent.FOCUS_IN , _focusInHandler , false , 0 , true);
            _focusInHandler (null);

        }



        public function isShortcutKey(keyCode:int):Boolean
        {
            return _shortcutKeyList[keyCode] != null;
        }





        private function _registShortcutKey():void
        {
            _shortcutKeyList[KEY_0] = 1;
            _shortcutKeyList[KEY_1] = 1;
            _shortcutKeyList[KEY_2] = 1;
            _shortcutKeyList[KEY_3] = 1;
            _shortcutKeyList[KEY_4] = 1;
            _shortcutKeyList[KEY_5] = 1;
            _shortcutKeyList[KEY_6] = 1;
            _shortcutKeyList[KEY_7] = 1;
            _shortcutKeyList[KEY_8] = 1;
            _shortcutKeyList[KEY_9] = 1;
            _shortcutKeyList[KEY_B] = 1;
            _shortcutKeyList[KEY_C] = 1;
            _shortcutKeyList[KEY_ESC] = 1;
        }

        //handlers
        private function _focusInHandler(e:Event):void
        {
            var io:InteractiveObject = _stage.focus;
            if (_focus != null)
            {
                _focus.removeEventListener (Event.REMOVED_FROM_STAGE , _focusRemovedFromStageHandler);
                _focus = null;
            }
            if (io != null)
            {
                if (io.stage == null)
                {
                    _stage.focus = _stage;
                    IME.enabled = false;
                }
                else
                {
                    _focus = io;
                    if (_focus is TextField)
                    {
                        IME.enabled = true;
                        _focus.addEventListener (FocusEvent.FOCUS_OUT , onTFFocusOut);
                    }
                    else
                    {
                        IME.enabled = false;
                    }
                    _focus.addEventListener (Event.REMOVED_FROM_STAGE , _focusRemovedFromStageHandler , false , 0 , true);
                }
            }
        }

        private function onTFFocusOut(e:Event):void
        {
            IME.enabled = false;
        }

        private function _focusRemovedFromStageHandler(e:Event):void
        {
            _focus.removeEventListener (Event.REMOVED_FROM_STAGE , _focusRemovedFromStageHandler);
            _focus = null;
            _stage.focus = _stage;
            IME.enabled = false;
        }

        private function _stageKeyDownHandler(event:KeyboardEvent):void
        {
            this.dispatchEvent (event);

            //Bug  5月18日游戏BUG整理 4
            var tf:TextField = _stage.focus as TextField;
            if (event.keyCode == KEY_ENTER)
            {
//                var cc:ChatController = ComponentManager.instance.getComponent (ComponentID.CHAT);
//                if (cc != null)
//                {
//                    if (cc.isFocusIn)
//                    {
//                        var text:String = cc.inputText;
//                        if (text.length == 0)
//                        {
//                            StageManager.instance.focus = null;
//                        }
//                        else
//                        {
//                            cc.sendText ();
//                        }
//                    }
//                    else if (tf == null || tf.type != TextFieldType.INPUT)
//                    {
//                        cc.focusIn ();
//                    }
//                }
            }
            else if (tf == null || tf.type != TextFieldType.INPUT)
            {
//				if (cc != null && !this.isShortcutKey(code)) {
//					cc.focusIn();
//					if (e.charCode != 0) cc.appendText(String.fromCharCode(e.charCode));
//				}
                var ke:KeyboardEvent = new KeyboardEvent (KeyboardEvent.KEY_DOWN + "_" + event.keyCode , event.bubbles , event.cancelable , event.charCode , event.keyCode , event.keyLocation , event.ctrlKey , event.altKey , event.shiftKey);
                this.dispatchEvent (ke);
            }
        }

        private function _stageKeyUpHandler(event:KeyboardEvent):void
        {
            var ke:KeyboardEvent = new KeyboardEvent (KeyboardEvent.KEY_UP + "_" + event.keyCode , event.bubbles , event.cancelable , event.charCode , event.keyCode , event.keyLocation , event.ctrlKey , event.altKey , event.shiftKey);
            this.dispatchEvent (ke);
        }
    }
}
